package com.kjlink.internal.report4vue.config;

import cn.dev33.satoken.strategy.SaStrategy;
import cn.xuqiudong.common.base.exception.CommonException;
import cn.xuqiudong.common.util.encrypt.AesUtil;
import com.kjlink.internal.workreport.base.constant.CommonConstant;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.math.BigInteger;

/**
 * 描述:
 * sa token
 *
 * @author Vic.xu
 * @since 2025-01-11 17:16
 */
@Configuration
public class SaTokenConfigure {

    private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(SaTokenConfigure.class);

    private static final ThreadLocal<String> CURRENT_SA_TOKEN = new InheritableThreadLocal<>();

    public static void setCurrentSaToken(String token) {
        CURRENT_SA_TOKEN.set(token);
    }

    public static String getCurrentSaToken() {
        return CURRENT_SA_TOKEN.get();
    }

    public static void removeCurrentSaToken() {
        CURRENT_SA_TOKEN.remove();
    }

    /**
     * 重写 Sa-Token 框架内部算法策略
     */
    @PostConstruct
    public void rewriteSaStrategy() {
        // 重写 Token 生成策略
        SaStrategy.instance.createToken = (loginId, loginType) -> {
            String currentSaToken = getCurrentSaToken();
            if (currentSaToken != null) {
                LOGGER.debug("current SaToken ({}) is reactivated", currentSaToken);
                return currentSaToken;
            }
            return generateToken(loginId);
        };
    }

    /**
     * 从sat-token中获取用户
     *
     * @return
     */
    public static Integer parseToken(String tokenHex) {
        if (tokenHex != null) {
            String tokenJson = new String(new BigInteger(tokenHex, 16).toByteArray());
            try {
                String decrypt = AesUtil.decrypt(tokenJson, CommonConstant.SPECIAL_USER_CODE);
                if (StringUtils.isBlank(decrypt)) {
                    return null;
                }
                String[] split = decrypt.split(":");
                if (split.length != 2) {
                    return null;
                }
                long timestamp = Long.parseLong(split[1]);
                //超时
                if (System.currentTimeMillis() - timestamp > 1000L * 60 * 60 * 24 * 7) {
                    return null;
                }
                return Integer.valueOf(split[0]);
            } catch (Exception e) {
                LOGGER.error("解析sa-token失败：｛｝", e.getMessage());
                return null;
            }
        }
        return null;
    }

    /**
     * 根据id生成token
     * token = id:timestamp
     */
    public static String generateToken(Object userId) {
        try {
            String text = userId + ":" + System.currentTimeMillis();
            String encrypt = AesUtil.encrypt(String.valueOf(text), CommonConstant.SPECIAL_USER_CODE);
            String tokenHex = new BigInteger(encrypt.getBytes()).toString(16);
            return tokenHex;
        } catch (Exception e) {
            throw new CommonException(e);
        }
    }

    public static void main(String[] args) throws Exception {
        int userId = 21;
        String tokenHex = generateToken(userId);
        System.out.println(tokenHex);
        System.out.println(parseToken(tokenHex));
    }
}
